package com.cloud.oss.minio.config;

import com.cloud.oss.minio.util.SslUtils;
import io.minio.MinioClient;
import io.minio.errors.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

/**
 * @author wangjian
 * @version 1.0.0
 * @create 2020年11月11日 10:20
 * @since JDK 1.8
 * Life is so short,do something to make yourself happy,such as coding
 */
@Configuration
@ConditionalOnClass(MinioClient.class)
@EnableConfigurationProperties(MinioConfigurationProperties.class)
@ComponentScan("com.cloud.oss.minio")
public class MinioAutoConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioAutoConfiguration.class);

    @Autowired
    private MinioConfigurationProperties minioConfigurationProperties;

    @Bean
    public MinioClient minioClient() throws InvalidPortException, InvalidEndpointException, IOException, InvalidKeyException, InvalidResponseException, RegionConflictException, InsufficientDataException, NoSuchAlgorithmException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, KeyManagementException {
        MinioClient minioClient;
        // 构建客户端连接
        try {
            //是否跳过ssl
            if (minioConfigurationProperties.isSkipSsl()) {
                minioClient = new MinioClient(
                        minioConfigurationProperties.getUrl(), minioConfigurationProperties.getPort(),
                        minioConfigurationProperties.getAccessKey(),
                        minioConfigurationProperties.getSecretKey(), null,
                        minioConfigurationProperties.isSecure(),
                        SslUtils.getUnsafeOkHttpClent()
                );
            } else {
                minioClient = new MinioClient(
                        minioConfigurationProperties.getUrl(),
                        minioConfigurationProperties.getAccessKey(),
                        minioConfigurationProperties.getSecretKey(),
                        minioConfigurationProperties.isSecure()
                );
            }
            // 设置超时时间
            minioClient.setTimeout(
                    minioConfigurationProperties.getConnectTimeout().toMillis(),
                    minioConfigurationProperties.getWriteTimeout().toMillis(),
                    minioConfigurationProperties.getReadTimeout().toMillis()
            );
        } catch (InvalidEndpointException | InvalidPortException | KeyManagementException e) {
            LOGGER.error("[minio] Error with connecting to Minio", e);
            throw e;
        }

        // 判断是否需要校验桶是否存在
        if (minioConfigurationProperties.isCheckBucket()) {
            try {
                LOGGER.debug("[minio] Checking if bucket {} exists", minioConfigurationProperties.getBucket());
                boolean exists = minioClient.bucketExists(minioConfigurationProperties.getBucket());
                if (!exists) {
                    if (minioConfigurationProperties.isCheckBucket()) {
                        minioClient.makeBucket(minioConfigurationProperties.getBucket());
                    } else {
                        // 返回不存在当前桶
                        throw new InvalidBucketNameException(minioConfigurationProperties.getBucket(), "Bucket does not exists");
                    }
                }
            } catch (InvalidResponseException | XmlParserException | InvalidBucketNameException | ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | IOException | NoSuchAlgorithmException | RegionConflictException e) {
                LOGGER.error("[minio] Error while checking bucket", e);
                throw e;
            }
        }
        return minioClient;
    }

}
